package com.crcchem.practice.demos.web.interceptor;

import com.crcchem.practice.demos.web.utils.JwtSuperUtil;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @projectName: code-training
 * @package: com.crcchem.practice.demos.web.interceptor
 * @className: JwtInterceptor
 * @author: 李富强
 * @description: TODO
 * @date: 2025/8/21 15:16
 * @version: 1.0
 */
/**
 * 自定义拦截器
 * 拦截器是一种AOP（面向切面编程）思想的实现，它能在方法调用前后自动进行一些逻辑处理，无需侵入业务代码。
 * 简单理解就是：你访问某个接口，拦截器可以在你“到达”接口之前或之后进行拦截处理，比如登录校验、日志记录、权限验证等。
 * 拦截器的执行顺序：
 * preHandle() → Controller方法 → postHandle() → 页面渲染 → afterCompletion()
 * 拦截器是Spring提供的一种AOP机制，可以在不修改Controller代码的前提下，灵活地实现功能增强，如登录校验、权限验证、日志记录等，且基于Spring MVC流程管理，使用起来非常高效和干净。
 */
@Component
public class JwtInterceptor implements HandlerInterceptor {
    // 请求前执行，返回false会中断请求
     @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /**
         * 预检请求
         * 预检请求是浏览器为保证安全性，在发送**某些跨域请求之前，先发送一个 HTTP OPTIONS 请求**，向服务器“询问”这个接口是否允许这样跨域。
         * 🔥 如果服务器回复“允许”，才会继续真正的业务请求。
         * 预检请求是浏览器自动发送的 OPTIONS 请求，目的是验证跨域是否合法。Java后端必须允许OPTIONS方法并返回正确的CORS响应头，才能让浏览器放行后续的真实请求。
         */
        if (request.getMethod().equals("OPTIONS")) {
            return true;
        }
        String authorization = request.getHeader("Authorization");
        if (authorization == null || !authorization.startsWith("Bearer ")) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        String token = authorization.replace("Bearer ", "");
        if (!JwtSuperUtil.validateToken(token)) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            return false;
        }
        return true;
    }
}
